<template>
  <div v-if="!canLogin" style="font-size: 16px">{{ systemStatus }}</div>
  <LoginFormTab v-if="canLogin" @change="handleChangeTab" :loginMode="loginMode" />
  <Form
    class="p-4 enter-x w-300px"
    style="margin: 0 auto"
    :model="formData"
    :rules="getFormRules"
    ref="formRef"
    v-if="canLogin"
    v-show="getShow"
    @keypress.enter="handleLogin"
  >
    <FormItem
      name="account"
      v-if="loginKind == 'account'"
      class="enter-x defs"
      style="margin-bottom: 26px; margin-top: 47px"
    >
      <Input
        size="large"
        v-model:value="formData.account"
        :placeholder="t('sys.login.userName')"
        class="fix-auto-fill input-account"
        :bordered="false"
      >
        <template #prefix>
          <img
            style="width: 21px; height: 18px; margin-right: 16px; margin-left: 24px"
            :src="userImg"
            alt=""
          />
        </template>
      </Input>
    </FormItem>
    <FormItem name="password" v-if="loginKind == 'account'" class="enter-x defs">
      <InputPassword
        class="fix-auto-fill input-account"
        size="large"
        :bordered="false"
        visibilityToggle
        v-model:value="formData.password"
        :placeholder="t('sys.login.password')"
      >
        <template #prefix>
          <img
            style="width: 17px; height: 21px; margin-right: 16px; margin-left: 24px"
            :src="lockImg"
            alt=""
          />
        </template>
      </InputPassword>
    </FormItem>
    <FormItem
      name="mobile"
      v-if="loginKind == 'mobile'"
      class="enter-x defs"
      style="margin-bottom: 26px; margin-top: 47px"
    >
      <Input
        size="large"
        v-model:value="formData.mobile"
        :placeholder="t('sys.login.mobile')"
        class="fix-auto-fill input-account"
        :bordered="false"
      >
        <template #prefix>
          <img
            style="width: 16px; height: 20px; margin-right: 16px; margin-left: 24px"
            :src="mobileImg"
            alt=""
          />
        </template>
      </Input>
    </FormItem>
    <FormItem name="validateCode" class="enter-x defs" v-if="loginKind == 'mobile'">
      <Input
        size="large"
        v-model:value="formData.validateCode"
        placeholder="验证码"
        class="fix-auto-fill input-account"
        :bordered="false"
      >
        <template #prefix>
          <img
            style="width: 19px; height: 22px; margin-right: 16px; margin-left: 24px"
            :src="mobileLockImg"
            alt=""
          />
        </template>
        <template #suffix>
          <div v-if="isDisabled" class="cursor-pointer mr-16px">
            {{ btnSendText }}
          </div>
          <div v-else @click="sendCode" class="cursor-pointer mr-16px">
            {{ btnSendText }}
          </div>
          <!-- <Button :disabled="isDisabled" @click="sendCode">{{ btnSendText }}</Button> -->
        </template>
      </Input>
    </FormItem>

    <!-- class="cursor-pointer" @click="">重置密码</ro> -->
    <!-- No logic, you need to deal with it yourself -->
    <!-- <ARow class="enter-x">
      <ACol :span="12">
        <FormItem>
          <Checkbox v-model:checked="rememberMe" size="small">
            {{ t('sys.login.rememberMe') }}
          </Checkbox>
        </FormItem>
      </ACol>
      <ACol :span="12">
        <FormItem :style="{ 'text-align': 'right' }">
          <Button type="link" size="small" @click="setLoginState(LoginStateEnum.RESET_PASSWORD)">
            {{ t('sys.login.forgetPassword') }}
          </Button>
        </FormItem>
      </ACol>
    </ARow> -->

    <FormItem class="enter-x mt-47px" v-if="loginKind == 'scan'">
      <div class="h-320px flex flex-col">
        <div class="flex flex-1">
          <div id="qrCodeBox" class="w-full flex justify-center items-center">
            <img :src="qrcodeImgUrl" />
          </div>
        </div>
        <div class="flex justify-center" :style="{ color: 'red' }" v-if="errMsg.length > 0">{{
          errMsg
        }}</div>
      </div>
    </FormItem>
    <FormItem
      class="enter-x"
      style="margin-bottom: 38px; margin-top: 64px"
      v-if="loginKind == 'account' || loginKind == 'mobile'"
    >
      <Button
        type="primary"
        size="large"
        block
        :loading="loading"
        class="butImg"
        @click="handleLogin"
      >
        {{ t('sys.login.loginButton') }}
      </Button>
    </FormItem>
    <div
      class="flex enter-x items-center"
      :class="{
        'justify-center':
          Number(isPwdCanReset) + Number(isUseClient) + Number(isWxLoginEnabled) === 1,
        'justify-between': !(
          Number(isPwdCanReset) + Number(isUseClient) + Number(isWxLoginEnabled) ===
          1
        ),
      }"
      v-if="loginKind == 'account' || loginKind == 'mobile'"
    >
      <router-link v-if="isPwdCanReset" :to="PageEnum.RESET_PASSWORD">{{
        t('sys.login.forgetPassword')
      }}</router-link>
      <div id="wxQrcode" style="position: absolute; display: none"></div>
      <div @click="handleShowWxQrcode" v-if="isWxLoginEnabled" style="width: 16px; height: 16px">
        <Icon
          icon="ant-design:wechat-outlined"
          title="微信扫码登录"
          class="cursor-pointer"
          style="opacity: 0.5"
        />
      </div>
      <div v-if="isUseClient" class="ml-2 flex">
        <img
          id="thumbnail"
          src="../../../assets/images/erwei.jpg"
          title="扫码下载APP"
          style="width: 16px; height: 16px"
          @mousemove="showQrcodeImg()"
          @mouseout="hideQrcodeImg()"
        />
        <img id="qrcodeImg" :src="qrcodeImgPath" style="position: absolute; display: none" />
      </div>
    </div>
    <!-- 为了使得登录后图标不需刷新就能显示，需在此调用一下图标 -->
    <!-- <Icon icon="ant-design:edit-outlined" size="0" style="display: none" /> -->
  </Form>
</template>
<script lang="ts" setup>
  import { reactive, ref, unref, computed, watch, onMounted, nextTick } from 'vue';

  import { Checkbox, Form, Input, Row, Col, Button, Divider } from 'ant-design-vue';

  import { useI18n } from '/@/hooks/web/useI18n';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { useRoute, useRouter } from 'vue-router';

  import { useUserStore } from '/@/store/modules/user';
  import { LoginStateEnum, useLoginState, useFormRules, useFormValid } from './useLogin';
  import { useDesign } from '/@/hooks/web/useDesign';
  import { PageEnum } from '/@/enums/pageEnum';
  import { getServerInfo } from '/@/api/process/process';
  import { wxLogin } from '/@/api/system/system';
  import { useGo } from '/@/hooks/web/usePage';
  import Icon from '/@/components/Icon/index';
  //import { onKeyStroke } from '@vueuse/core';
  import userImg from '/@/assets/images/login-user.png';
  import lockImg from '/@/assets/images/login-lock.png';
  import mobileImg from '/@/assets/images/login-mobile.png';
  import mobileLockImg from '/@/assets/images/login-mobile-lock.png';
  // import wxlogin from 'vue-wxlogin';
  import { sendValidateCodeForMobileLogin } from '/@/api/system/system';
  import LoginFormTab from './LoginFormTab.vue';
  import { getQrCodeForLogin, getQrCodeLoginCheck } from '/@/api/system/system';
  import { useDebounceFn } from '@vueuse/core';

  const ACol = Col;
  const ARow = Row;
  const FormItem = Form.Item;
  const InputPassword = Input.Password;
  const { t } = useI18n();
  const { notification, createErrorModal, createMessage } = useMessage();
  const { prefixCls } = useDesign('login');
  const userStore = useUserStore();

  const { setLoginState, getLoginState } = useLoginState();
  const { getFormRules } = useFormRules();

  const formRef = ref();
  const loading = ref(false);
  const canLogin = ref(true);
  const systemStatus = ref('');
  const rememberMe = ref(false);

  const formData = reactive({
    account: '',
    password: '',
    mobile: '',
    validateCode: '',
  });

  const { validForm } = useFormValid(formRef);
  const isWxLoginEnabled = ref(false);
  const isMobileLoginEnabled = ref(false);
  const loginKind = ref('account');

  //onKeyStroke('Enter', handleLogin);

  const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN);

  const getQrcodeSpan = computed(() => {
    return (
      24 -
      (isWxLoginEnabled.value ? 3 : 0) -
      (isMobileLoginEnabled.value ? 3 : 0) -
      (isPwdCanReset.value ? 6 : 0)
    );
  });

  // AES密钥 (需要前端和后端保持一致，十六位)
  var KEY = 'njyyhlrjcloudweb';
  // AES密钥偏移量 (需要前端和后端保持一致，十六位)
  var IV = 'cloudwebnjyyhlrj';
  var pwdName = 'wdmm';
  const qrcodeImgPath = ref('');
  const isPwdCanReset = ref(true);
  const go = useGo();
  const emit = defineEmits(['showId']);
  const isUseClient = ref(false); // 是否启用手机端
  const route = useRoute();
  const errMsg = ref('');
  const qrcodeImgUrl = ref('');
  const loginMode = ref(3);

  function aesDecrypt(word, KEY, IV) {
    var _key = CryptoJS.enc.Utf8.parse(KEY);
    var _iv = CryptoJS.enc.Utf8.parse(IV);
    var decrypted = CryptoJS.AES.decrypt(word, _key, {
      iv: _iv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7,
    });
    return decrypted.toString(CryptoJS.enc.Utf8);
  }

  const { currentRoute } = useRouter();

  const isDisabled = ref(false);
  const btnSendText = ref('发送');
  const wxAppId = ref('');
  const frontPath = ref('');

  getServerInfo().then((res) => {
    if (res.hasOwnProperty('isPwdCanReset')) {
      isPwdCanReset.value = res.isPwdCanReset == 1;
    }
    if (res.hasOwnProperty('url')) {
      qrcodeImgPath.value = res.url + '/public/images/yimioa_mobile_qrcode.png';
    }
    pwdName = res.pwdName;
    KEY = res.pak; // pwdAesKey
    IV = res.pai; // pwdAesIV

    KEY = decodeURIComponent(atob(KEY));
    IV = decodeURIComponent(atob(IV));
    // console.log('IV', IV);

    emit('showId', { showId: res.showId, id: res.id });

    let systemIsOpen = res.systemIsOpen;
    let systemLoginParam = res.systemLoginParam;
    systemStatus.value = res.systemStatus;
    isWxLoginEnabled.value = res.isWxLoginEnabled;
    isMobileLoginEnabled.value = res.isMobileLoginEnabled;

    systemLoginParam = aesDecrypt(systemLoginParam, KEY, IV);
    // console.log('systemLoginParam', systemLoginParam);
    console.log('currentRoute.value.query', currentRoute.value.query);
    if (!systemIsOpen) {
      if (currentRoute.value.query && currentRoute.value.query.op) {
        if (currentRoute.value.query.op !== systemLoginParam) {
          canLogin.value = false;
        }
      } else {
        canLogin.value = false;
      }
    }

    isUseClient.value = res.isUseClient;
    loginMode.value = res.loginMode;
    // 如果只允许扫码登录，则重定向至扫码登录页
    // if (loginMode.value === 1) {
    //   go(PageEnum.QRCODE_LOGIN);
    // }

    if (loginMode.value == 1 || loginMode.value == 5) {
      loginKind.value = 'mobile';
    } else if (loginMode.value == 2) {
      loginKind.value = 'scan';
      getQrCodeForLogin().then(async (data) => {
        qrcodeImgUrl.value = data.QRCodeImg;
        let uuid = data.uuid;
        check(uuid);
      });
    }

    wxAppId.value = res.wxAppId;
    frontPath.value = res.frontPath;
  });

  async function handleLogin() {
    const data = await validForm();
    if (!data) return;
    try {
      loading.value = true;
      let params;
      if (loginKind.value == 'account') {
        params = {
          // wdmm: aesMinEncrypt(data.password),
          name: data.account,
          kind: 'account',
          mode: 'none', //不要默认的错误提示
        };
        params[pwdName] = aesMinEncrypt(data.password);
      } else {
        params = {
          name: data.mobile,
          validateCode: data.validateCode,
          kind: 'mobile',
          mode: 'none', //不要默认的错误提示
        };
      }

      const userInfo = await userStore.login(params);
      if (userInfo) {
        notification.success({
          message: t('sys.login.loginSuccessTitle'),
          description: `${t('sys.login.loginSuccessDesc')}: ${userInfo.realName}`,
          duration: 3,
        });
      }
    } catch (error) {
      createErrorModal({
        title: t('sys.api.errorTip'),
        content: (error as unknown as Error).message || t('sys.api.networkExceptionMsg'),
        getContainer: () => document.body.querySelector(`.${prefixCls}`) || document.body,
      });
    } finally {
      loading.value = false;
    }
  }

  function aesMinEncrypt(word: string) {
    var _word = CryptoJS.enc.Utf8.parse(word),
      _key = CryptoJS.enc.Utf8.parse(KEY),
      _iv = CryptoJS.enc.Utf8.parse(IV);
    var encrypted = CryptoJS.AES.encrypt(_word, _key, {
      iv: _iv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7,
    });
    return encrypted.toString();
  }

  function showQrcodeImg() {
    console.log("$('#position').offset()", $('#thumbnail').position());
    $('#qrcodeImg').show();
    // 注意.ant-col为relative
    $('#qrcodeImg').css('top', -$('#qrcodeImg').height() + 'px');
    $('#qrcodeImg').css(
      'left',
      `${$('#thumbnail').position().left - $('#qrcodeImg').width() / 2}px`,
    );
  }

  function hideQrcodeImg() {
    $('#qrcodeImg').hide();
  }

  const WxLogin = function (e) {
    var r = 'default';
    !0 === e.self_redirect ? (r = 'true') : !1 === e.self_redirect && (r = 'false');
    var n = document.createElement('iframe'),
      i =
        'https://open.weixin.qq.com/connect/qrconnect?appid=' +
        e.appid +
        '&scope=' +
        e.scope +
        '&redirect_uri=' +
        e.redirect_uri +
        '&state=' +
        e.state +
        '&login_type=jssdk&self_redirect=' +
        r +
        '&styletype=' +
        (e.styletype || '') +
        '&sizetype=' +
        (e.sizetype || '') +
        '&bgcolor=' +
        (e.bgcolor || '') +
        '&rst=' +
        (e.rst || '');
    (i += e.style ? '&style=' + e.style : ''),
      (i += e.href ? '&href=' + e.href : ''),
      (i += 'en' === e.lang ? '&lang=en' : ''),
      (n.src = i),
      (n.frameBorder = '0'),
      (n.allowTransparency = 'true'),
      (n.scrolling = 'no'),
      (n.width = '300px'),
      (n.height = '400px');
    n.setAttribute('sandbox', 'allow-top-navigation allow-scripts allow-same-origin');
    var s = document.getElementById(e.id);
    (s.innerHTML = ''), s.appendChild(n);
  };

  // 显示微信登录二维码
  const handleShowWxQrcode = () => {
    if ($('#wxQrcode').is(':hidden')) {
      //css内容
      var content =
        '#impowerBox { margin-top: 150px} .impowerBox .qrcode {width: 200px;} .impowerBox .impowerBox .info {width: 200px;} .js_wx_default_tip{display:none}';
      //记住一定要注明文件类型是css
      var blob = new Blob([content], { type: 'text/css;charset=utf-8' });

      var reader = new FileReader();
      reader.readAsDataURL(blob);
      reader.onload = function (e) {
        let url = frontPath.value + 'login';
        console.log('handleShowWxQrcode url', url);
        var obj = new WxLogin({
          id: 'wxQrcode', // 需要显示的容器id
          appid: wxAppId.value,
          scope: 'snsapi_login',
          redirect_uri: encodeURIComponent(url),
          state: new Date().getTime() + '' + Math.ceil(Math.random() * 1000), //建议使用时间戳+随机数，具体看你
          style: 'style', // 提供"black"、"white"可选。二维码的样式
          href: this.result, // 外部css文件url，需要https，或者使用base64编码的css
        });

        $('#wxQrcode').show();
        // 注意.ant-col为relative
        $('#wxQrcode').css({
          'background-color': '#fff',
          'border-radius': '8px',
          left: '0px',
          top: -$('#wxQrcode').height() + 'px',
        });
      };
    } else {
      $('#wxQrcode').hide();
    }
  };

  const handleWxLogin = async (code) => {
    let data = await wxLogin({ code: code });
    console.log('data', data);
    if (data.Authorization) {
      userStore.setServerUrl(data.serverInfo.url);
      userStore.setServerInfo(data.serverInfo);
      userStore.setToken(data.Authorization);

      // 不能直接go，因为还需要在afterLoginAction中调用getUISetup，否则界面上会显示为白色
      // go(PageEnum.BASE_HOME);
      userStore.afterLoginAction(true);
    } else {
      if (data.errcode) {
        createMessage.warn('已超时，请重新扫码');
      } else {
        go({
          path: PageEnum.REGIST_BY_WX,
          query: { nickName: data.nickname, openId: data.openid, sex: data.sex },
        });
      }
    }
  };

  if (currentRoute.value.query.code) {
    handleWxLogin(currentRoute.value.query.code);
  }

  let c = 60;
  async function sendCode() {
    const fields = await validForm();
    console.log('fields', fields);
    if (!fields.mobile) {
      createMessage.warn('请输入手机号');
      return;
    }
    sendValidateCodeForMobileLogin({ mobile: fields.mobile });
    btnSendText.value = '重新发送(' + c + ')';
    isDisabled.value = true;
    c = 60;

    let sint = setInterval(() => {
      c--;
      if (c == 0) {
        btnSendText.value = '发送';
        clearInterval(sint);
        isDisabled.value = false;
      } else {
        btnSendText.value = '重新发送(' + c + ')';
      }
    }, 1000);
  }

  function handleMobileLogin() {
    if (loginKind.value == 'account') loginKind.value = 'mobile';
    else loginKind.value = 'account';
  }

  // 防抖，延迟500ms执行
  const handleWxLoginDebounce = useDebounceFn(handleWxLogin, 500);

  watch(
    () => route.query,
    (val) => {
      if (val.code && val.state) {
        console.log('watch val', val);
        handleWxLoginDebounce(val.code);
      }
    },
  );

  const handleChangeTab = (val) => {
    loginKind.value = val;
    if (val == 'scan') {
      getQrCodeForLogin().then(async (data) => {
        qrcodeImgUrl.value = data.QRCodeImg;
        let uuid = data.uuid;
        check(uuid);
      });
    }
  };

  function check(uuid) {
    let params = {
      uuid: uuid,
    };
    getQrCodeLoginCheck(params)
      .then((res) => {
        if (res.code == 200) {
          userStore.setServerUrl(res.data.serverInfo.url);
          userStore.setServerInfo(res.data.serverInfo);
          userStore.setToken(res.data.Authorization);

          // go(PageEnum.BASE_HOME);
          // 不能直接go，因为还需要在afterLoginAction中调用getUISetup，否则界面上会显示为白色
          // go(PageEnum.BASE_HOME);
          userStore.afterLoginAction(true);
        } else {
          if (loginKind.value == 'scan') {
            console.log(res.msg);
            errMsg.value = res.msg;
          }
        }
      })
      .catch((e) => {
        if (loginKind.value == 'scan') {
          console.log(e.message);
          errMsg.value = e.message;
        }
      });
  }

  onMounted(async () => {});
</script>
<style lang="less" scoped>
  .butImg {
    background: transparent;
    border: none;
    background-image: url(/@/assets/images/login-but.png);
    background-position: 100%;
    background-repeat: no-repeat;
    background-size: 100% 100%;
  }
  // .defs :deep(.ant-form-item-control-input) {
  //   border-bottom: 1px dashed #ccc !important;
  // }
  /*定宽，否则切换手机端登录，因为验证码发送按钮宽度会被撑开 */
  .defs {
    width: 100%;
  }
  :deep(input) {
    min-width: unset !important;
  }
  :deep(a:visited) {
    color: #c6c6c6;
  }
  :deep(.ant-input::placeholder) {
    color: #c6c6c6;
  }
  .input-account {
    height: 56px;
    // 输入的文字颜色修改
    // -webkit-text-fill-color: #3da4f9;
    background-color: #f2f4f8;
    :deep(input) {
      font-size: 16px;
    }
    :deep(input:-webkit-autofill) {
      background-color: transparent !important; /* 确保与一般状态一致 */
      -webkit-box-shadow: 0 0 0px 1000px transparent inset !important; /* 强制背景颜色 */
    }
    :deep(input:-moz-autofill) {
      background-color: transparent !important;
      /* 注意：Firefox对自动填充样式的支持有限 */
    }

    // 这里是 placeholder 的颜色样式
    :deep(input::-webkit-input-placeholder) {
      -webkit-text-fill-color: #8a8989;
      font-weight: 500;
      font-size: 16px;
      color: #8a8989;
    }
    :deep(input::-moz-placeholder) {
      -webkit-text-fill-color: #8a8989;
      font-weight: 500;
      font-size: 16px;
      color: #8a8989;
    }
    :deep(input:-ms-input-placeholder) {
      -webkit-text-fill-color: #8a8989;
      font-weight: 500;
      font-size: 16px;
      color: #8a8989;
    }
  }
</style>
